import store from '@jsjn/micro-core-store'
import packInfo from '@ROOT/package.json'
import { Router } from 'vue-router'
import { ElMessage } from 'element-plus'
import _ from 'lodash'

/**
 * 后端路由创建
 * 在进入微应用的路由之前，基座应用的路由一定是创建好的
 * 所以微应用在初始化时，就可以拿到基座应用中的所有已注册路由了
 * 因此，在微应用中，后台路由的处理是同步的
 */
export default (router: Router) => {
    /**
     * remoteRegisteredRoutes 中包含了所有应用的路由
     * - 基座应用
     * - 当前微应用
     * - 其他兄弟微应用
     */
    const remoteRegisteredRoutes = _.cloneDeep(store.state.appFuncTree.remoteRegisteredRoutes)

    /**
     * 筛选出当前应用的路由
     * - 以系统 name 开头
     * - 排除基座应用注册的保险路由（xxx/:page*）
     */
    const currentSysRoutes = remoteRegisteredRoutes.filter(
        (route) => route.path.startsWith(`/${packInfo.name}`) && !route.path.endsWith(':page*')
    )

    const registeredRoutes = currentSysRoutes.map((route) => {
        const componentPath = route.meta.componentPath
        const pathSplit = componentPath.split('/views/')
        const pageFile = pathSplit[1]

        /**
         * 历史遗留问题，路由的路径需要带有微应用标识，有好处有坏处
         *  - 坏处：需要添加额外的前缀，无界本身是不需要的
         *  - 好处：与基座路由同步，易于阅读
         */
        route.path = route.path.replace(`/${packInfo.name}`, `/${window.__WUJIE.id}`)

        // 如果页面标识模糊匹配，需要添加 /:page* 的 params
        if (route.meta.isBlurry) {
            route.path = `${route.path}/:page*`
        }

        /**
         * 替换当前系统的 filePath
         * 具体的微应用在引用当前模块时，会解析 @ 符号
         * 每个微应用的 vue.config.js 里都将 @ 别名配置为本地文件夹
         * 所以，这里直接使用 @/ 可以定位到自己的文件夹下
         * 相当于自适应匹配
         */
        route['component'] = () =>
            // 1. 首先加载项目本地的 views 目录下的文件
            import(`@/views/${pageFile}`)
                // 2. 如果未加载到，就去公用页面加载
                .catch(() => import(`@jsjn/common-module/views/${pageFile}`))
                // 3. 公用模块也没有，则抛出错误页面
                .catch((err) => {
                    ElMessage.error({
                        message: `${componentPath} 加载失败，错误信息：${err}`,
                        type: 'error',
                        duration: 0,
                        showClose: true
                    })
                    return import('@jsjn/micro-core-views/error/pageLoadErr.vue')
                })

        // 更新重新注册
        router.hasRoute(route.name) && router.removeRoute(route.name)
        router.addRoute(route as any)
        return route
    })
    store.commit('appFuncTree/setRegisteredRoutes', registeredRoutes)
}
